#pragma once

#include "BondDetailCache.h"
#include <bondlib/BondInfo.h>
#include <bondlib/BondMarketStream.h>
#include <qbtools/message/MessagePoster.h>
#include <qbprotocol/include/SSIDBModel.h>
#include "./BondChart/bondcharttools.h"
#include <qbnet/include/network_service.h>
#include <QColor>
#include <QObject>
#include <string>
#include <vector>
#include <map>


class xQBBondGradeInstitutionUnit;
class xQBBondCDCSpecialInfoUnit_c;
class BondDetailDlg;
enum CRmType
{
	crm_null = 0,
	crm_crm, // //crm券
	crm_cln, //cln券
	crm_crm_refer, //crm标的券
	crm_cln_refer, //cln标的券
};

enum kDetailAprsmtCompany
{
	KDETAIL_APRSMT_CCDVAL = 0,//中债估值
	KDETAIL_APRSMT_ZZVAL = 1,//中证估值
	KDETAIL_APRSMT_SQSVAL = 2,//上清估值
};

enum emWndType {
	wndTp_Null = 0,//暂无数据 不显示Tab，标题为信用利差
	wndTp_Lock,//无权限
	wndTp_Issuer,//只有主体信用利差  不显示Tab
	wndTp_Bond,//只有个券信用利差  不显示Tab
	wndTp_Both,
	wndTp_Max
};

#define DETAIL_QUOTE_MIN_WIDTH 480

#define  DETAILOTHERTYPE_BROKER      100
#define  DETAILOTHERTYPE_CFETS       101
#define  DETAILOTHERTYPE_EXCHANGE    102

struct TitleParams
{
	QString m_companyName;
	QString m_strRemain;//剩余期限
	QString m_strInterest; //票面利率
	QString m_strIssuer;//主体评级
	QString m_strIssuerInstituteName;//主体评级机构
	QString m_strRating;//债项评级
	QString m_strRatingInstituteName;//债项评级机构
	QString m_strChinaDCRating;//中债资信评级
	QString m_strChinaDCState;

	QString m_strApp;//中债估值
	QString m_strAppClean;//中债估值净价
	QString m_strAppDate;

	QString m_strZZ;//中证估值
	QString m_strZZClean;//中证估值净价

	QString m_strZZDate;

	QString m_strIssuerName;//发行人

	QString m_strRealPrice;//实时行情 
	QString m_strTrade;//成交方向
	QString m_strBP;//±BP
	QString m_strYestodayPrc;//昨收
	QString m_strOpenPrc;//开盘
	QString m_strLowPrc;//最低
	QString m_strHighPrc;//最高
    QString m_strTransCount;//成交笔数
    QString m_strTKNCount;
    QString m_strGVNCount;
    QString m_strTRDCount;
	QString m_strCrmKey;
	QString m_strCDCImplied;//中债隐含 added by shiy20210719
	QString m_strRatePattern;//利率方式
	QString m_strOptoinType;//含权类型
	QString m_strScorLevel;//流动性评级
	bool  m_bShowFullPrice = false;//展示FULLPRICE图标
	QColor m_clrBP;
};

struct CCrossMarketInfo
{
	std::vector<QString> m_vtCorpId;
	tBondKey	m_sBondKey;
	char		m_sCombCode[20];
	char		m_sListedMarket[8];
	char		m_sShorName[64];
	bool		m_showTips;
};

typedef struct ReqDaySaveStruct
{
	int nCDCReqDay;//中债估值已经请求的天数
	int nSQSReqDay;//上清所估值已经请求的天数
	int nZZReqDay;//中证估值已经请求的天数
	ReqDaySaveStruct() { nCDCReqDay = 0; nSQSReqDay = 0; nZZReqDay = 0; }
}ReqDaySaveType;

class DetailData 
	: public QObject
	, public MessageReceiver
	, public CUnknownObject<INetworkEventObserver>
{
	Q_OBJECT
public:
	DetailData(BondDetailDlg* p);
	~DetailData();
	void setCombondKey(const char* bondKey = nullptr, int brokerId = -1);
	std::string comBondKey() const { return m_combondKey; }
	QString shortName() const { return m_shortName; }
	QString code() const { return m_code; }
	const CBondInfo& bond() const { return m_bond; }
	CRmType crmType() const { return m_crmType; }
	bool showCrmLink() const { return m_crmType == crm_crm || m_crmType == crm_cln_refer || m_crmType == crm_crm_refer; }
	QString crmString() const;
	bool firstBond() const { return m_firstBond; }
	const TitleParams& titleParams() const { return m_titleParams; }
	int brokerId() const { return m_brokerId; }
	void setBrokerId(int v) { m_brokerId = v; }
	int clearSpeed() const { return m_clearSpeed; }
	void setClearSpeed(int v);
	int cfetsDealNum() const { return m_mapMktStreamDealCfets.size(); }

	void setBondType(em_BrokerKinds emCurType) { m_emCurBondType = emCurType; emit bondTypeChanged(); }//设置债券类型：broker or 交易所
	int getBondType() { return m_emCurBondType; }
	void setTabDayLineType(int tabType) { m_iTabDayLineType = tabType; }
	int getTabDayLineType() { return m_iTabDayLineType; }
	void setCDCType(em_NewDetail type) { m_cdcType = type; }
	em_NewDetail cdcType() { return m_cdcType; }
	bool hasMktStreamRight() const { return m_mktStreamRight; }
	bool isShowYieldChart();
	int getWndType();

	std::string& dealPreClose() { return m_PreClose; }

	void GetChartMktStreamData(xQBMarketStreamList_c& mkt);
	void GetChartMktStreamDealData(xQBMarketStreamList_c& mkt);
	bool IsValidChartData(const xQBMarketStreamUnit_c& unt);
	BondDetailDlg* getBondDetailDlg() { return m_dlg; }

	std::map<int, xQBMarketStreamUnit_c> marketStream() const;
	std::map<int, xQBMarketStreamUnit_c> cfetsMarketStream() const;
	std::map<std::string, xQBMarketStreamUnit_c> marketDeal() const { return m_mapMktStreamDeal; }
	std::map<std::string, xQBMarketStreamUnit_c> marketDealCfets() const { return m_mapMktStreamDealCfets; }
	std::vector<CCrossMarketInfo> crossMarketData() const { return m_vtCrossData; }

	xQBABrokerDealKlineDayList_c* dealKLineDayList() const { return m_pDataDayKline; }
	xQBABrokerKlineDayCloseList_Ack* dealKLineDayCloseList() const { return m_pDataCloseDayKline; }
	xQBABrokerKlineDayCloseBoList_c* boKLineDayCloseList() const { return m_pDataDayCloseBoKline; }

	void reqMarketStream(int index);
	void reqCfetsMarketStream(int index);
	void reqDealChartData();
	void reqAndSubExBestQuote();
	void unSubExBestQuoteReg();
	void reqCDCChartData(BondDetailChartData& data);
	void clearData();
	void setBondInfo(CBondInfo& bi);
    void reqSHFIData(bool push);
    void reqExchangeData(bool push);
protected:
	void onCombondKeyChanged(const char* bondKey);
	void onDataArrived(const qb::SSAckMsg& msg) override;

	// INetworkEventObserver
	STDMETHOD_(void, OnForceQuit) (THIS_ int32_t connect_id) {}
	STDMETHOD_(void, OnDisConnect) (THIS_ int32_t connect_id) {}
	STDMETHOD_(void, OnRecover) (THIS_ int32_t connect_id);

signals:
	void bondChanged();
	void bondTypeChanged();
	void hisPriceChanged();
	void issueInfoChanged();
	void cdcChanged();
	void cdcChartChanged();
	void dealChartKLineChanged(int type);
	void dealChartMarketDealChanged();
	void rateChartChanged();
	void interestChartChanged();
	void marketStreamChanged(QList<int> ids);
	void cfetsMarketStreamChanged(QList<int> ids);
	void mktStreamDealChanged(QList<QString> ids);
	void mktStreamDealCfetsChanged(QList<QString> ids);
	void brokerBestQuoteChanged(xQBBestPriceSynthetical_Unit_c, xQBBestPriceSynthetical_Unit_c, bool);//5家最优
	void clearSpeedChanged();
	void brokerBestPriceChanged(std::map<std::string, int>);
	void crossMarketQuoteChanged();
	void notifyPrimaryAprismtGetMapData();
    void SHFIDataChanged(QList<xQBSHFIQuoteUnit_c>);
    void ExchangeDataChanged(QList<xQBExQuoteUnit_c>);

protected slots:
	void onMarketDealChanged(int funcId, QString strKey, QList<xQBMarketStreamUnit_c> lstMarketStreamDeal);
	void onBestPriceArrived(std::string strKey, QList<xQBBestPriceUnit_c> lstBestPrice);

private:
	void setCrmType();
	void getCrossMarkertInfo();  
	void addBondInfo(int bondIndex);	
	void getCompanyBondInfo();
	void fillTitleParam();
	void reqBasicData();
	void reqChartData();
	void reqChartData(em_NewDetail type, int bondIndex = -1);
	void reqDealChartData(BondDetailChartData& data);
	void reqRateChartData(BondDetailChartData& data);
	void reqInterestChartData(BondDetailChartData& data);
	void getSpecialCDC();
	void reqDealData();
	void reqAppraisementData(em_NewDetail type, const char* combondKey, const CBondInfo& bondInfo);
	void reqAppraiseDataByParam(const CBondInfo& bondInfo, time_t req_StartTime, time_t req_EndTime, int reqID);
	void reqAndSubBestPriceSynthetical();
	void unSubBestPriceSynthetical();
	
	void clearPrice();
	void setPrice(xSingleBondQuotationAck_c* ptrQuot);
	void setIssuerInfo(const xQBBondGradeInstitutionUnit* unt);
	void setSpecialCDCInfo(const xQBBondCDCSpecialInfoUnit_c* unt);
	bool getAddDays(const CBondInfo& bondInfo, em_NewDetail type, int& func, int& reqDays);
	void updateRecommendValue(xQBCDCPriceSingleHisAck_c* priceData, int nAprsmtCmpy, const QString& strCombKey);

	bool InsertMktStreamDeal(const MarketStreamInfo& mktInfo, std::map<std::string, xQBMarketStreamUnit_c>&);
	bool InsertMktStreamDeal(const xQBMarketStreamUnit_c& mktInfo, std::map<std::string, xQBMarketStreamUnit_c>&);

private:
	BondDetailDlg* m_dlg;
	std::string	m_combondKey;
	std::string m_bondKey;
	std::string m_listMarket;
	QString	m_shortName;
	QString	m_code;
	CBondInfo m_bond;
	CRmType	m_crmType = crm_null;
	QString m_strCrmKey;
	TitleParams	m_titleParams;
	QBExQuoteQuery_t m_req;
	std::vector<CCrossMarketInfo> m_vtCrossData;

	xSingleBondQuotationReq_c m_hisReq;
	std::string				  m_hisReqParam;
	std::string				  m_PreClose;
	bool					  m_firstBond = false;
	bool					  m_bExchangeRight = false;
	bool					  m_bCFETSRight = false;
	bool					  m_mktStreamRight = false;
	bool					  m_hasBestQuoteRight = false;
	
	int						  m_brokerId = -1;	
	volatile int			  m_clearSpeed = 0;
	int						  m_nLastBestQuoteVersion = 0;

	/*mktstream数据*/
	std::map<int, xQBMarketStreamUnit_c> m_mapMktStream;
	std::map<int, xQBMarketStreamUnit_c> m_mapCfetsMktStream;
	/*成交数据*/
	std::map<std::string, xQBMarketStreamUnit_c> m_mapMktStreamDeal;
	std::map<std::string, xQBMarketStreamUnit_c> m_mapMktStreamDealCfets;
	/*交易所成交请求缓存*/
	xQBQuoteQuery_t			  m_ExReqDealCache;
	QBQuoteQuery_t			  m_reqCFETSDeal, m_reqCFETSMKt;

	xQBABrokerDealKlineDayList_c* m_pDataDayKline = nullptr;
	xQBABrokerKlineDayCloseList_Ack* m_pDataCloseDayKline = nullptr;
	xQBABrokerKlineDayCloseBoList_c* m_pDataDayCloseBoKline = nullptr;
	/*broker权限*/
	std::map<int, bool>		  m_mapBrokerAuthority;

	em_BrokerKinds			  m_emCurBondType;
	int						  m_iTabDayLineType;
	int						  m_iTabQuoteDayLineType; //报价收盘价类型0收益率，1净价

	em_NewDetail			  m_cdcType;
	std::map<std::string, ReqDaySaveType> m_ReqAprismtDay;

	long m_lReqExDealKLineIDEx, m_lReqExDealKLineIDBroker, m_lReqYieldCurve;
	long m_lReqExDealKLineIDCloseEx, m_lReqExDealKLineIDCloseBroker, m_lReqExDealKLineCfetsCloseEx;/*收盘曲线*/;
};
